package org.yaukie.builder;

 import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.KeyMatcher;
 import org.quartz.impl.triggers.CronTriggerImpl;
 import org.yaukie.util.DateTime;

 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;

/**
 *  @Author: yuenbin
 *  @Date :2020/11/13
 * @Time :14:12
 * @Motto: It is better to be clear than to be clever !
 * @Destrib:  写一个调度执行器管理
**/
public class QuartzManager {

	public static SchedulerFactory schedulerFactory = new StdSchedulerFactory();

	/**
	 *  @Author: yuenbin
	 *  @Date :2020/11/13
	 * @Time :14:13
	 * @Motto: It is better to be clear than to be clever !
	 * @Destrib:  执行调度策略
	**/
    public static void addJob(Map param ,Class<? extends Job> jobClass, String cron, Map<String, Object> parameter) {
        try {
            Scheduler sched = schedulerFactory.getScheduler();
            // 任务名，任务组，任务执行类
            JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(param.get("jobName")+"",
                    param.get("jobGroupName")+"").build();
            // 添加任务执行的参数
            parameter.forEach((k, v) -> {
            	jobDetail.getJobDataMap().put(k, v);
            });            
            // 触发器
            TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
            // 触发器名,触发器组
            triggerBuilder.withIdentity(
                    param.get("triggerName")+"",
                    param.get("triggerGroupName")+"");
            triggerBuilder.startNow();
            // 触发器时间设定
            triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
            // 创建Trigger对象
            CronTrigger trigger = (CronTrigger) triggerBuilder.build();
            // 调度容器设置JobDetail和Trigger
            sched.scheduleJob(jobDetail, trigger);
            // 启动  
            if (!sched.isShutdown()) {  
                sched.start();  
            }  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  
    
/**
 *  @Author: yuenbin
 *  @Date :2020/11/13
 * @Time :14:13
 * @Motto: It is better to be clear than to be clever !
 * @Destrib:  调度一次策略
**/
    public static void addOnceJob(Map param, Class<? extends Job> jobClass, Map<String, Object> parameter){
    	try {
    		Scheduler sched = schedulerFactory.getScheduler();
    		// 任务名，任务组，任务执行类
            JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(
                    param.get("jobName")+"",
                    param.get("jobGroupName")+"").build();
            // 添加任务执行的参数
            parameter.forEach((k, v) -> {
            	jobDetail.getJobDataMap().put(k, v);
            });
            // 触发器
            TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
            // 触发器名,触发器组
            triggerBuilder.withIdentity(
                    param.get("triggerName")+"",
                    param.get("triggerGroupName")+"");
            triggerBuilder.startNow();
            //立即执行
            StringBuilder cronBuilder = new StringBuilder();
    		DateTime dateTime = new DateTime();
    		Integer addMinute = dateTime.second() >= 58 ? 2 : 1;
    		cronBuilder.append("0").append(" ")
    						.append(dateTime.minute() + addMinute).append(" ")
    						.append(dateTime.hour(true)).append(" ")
    						.append(dateTime.dayOfMonth()).append(" ")
    						.append(dateTime.monthStartFromOne()).append(" ")
    						.append("?").append(" ")
    						.append(String.valueOf(dateTime.year()));
            // 触发器时间设定
            triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cronBuilder.toString()));
            // 创建Trigger对象
            CronTrigger trigger = (CronTrigger) triggerBuilder.build();
            // 调度容器设置JobDetail和Trigger
            sched.scheduleJob(jobDetail, trigger);
            // 添加任务执行监听器
            sched.getListenerManager().addJobListener(new QuartzListener(), 
            		KeyMatcher.keyEquals(new JobKey(param.get("jobName")+"",
                            param.get("jobGroupName")+"")));
            // 启动  
            if (!sched.isShutdown()) {  
                sched.start();  
            }             
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /** 
     * @Description: 修改一个任务的触发时间
     * @param cron   时间设置，参考quartz说明文档   
     */  
    public static void modifyJobTime(Map param, String cron) {
        try {  
            Scheduler sched = schedulerFactory.getScheduler();  
            TriggerKey triggerKey = TriggerKey.triggerKey(
                    param.get("triggerName")+"",
                    param.get("triggerGroupName")+"");
            CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);  
            if (trigger == null) {  
                return;  
            }
            String oldTime = trigger.getCronExpression();  
            if (!oldTime.equalsIgnoreCase(cron)) { 
                /** 方式一 ：调用 rescheduleJob 开始 */
                // 触发器  
                TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
                // 触发器名,触发器组  
                triggerBuilder.withIdentity(
                        param.get("triggerName")+"",
                        param.get("triggerGroupName")+"");
                triggerBuilder.startNow();
                // 触发器时间设定  
                triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));

                // 创建Trigger对象
                trigger = (CronTrigger) triggerBuilder.build();

                // 方式一 ：修改一个任务的触发时间
                sched.rescheduleJob(triggerKey, trigger);
            }  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }



    /** 
     * @Description: 移除一个任务
     *
     * @param jobName
     * @param jobGroupName
     * @param triggerName
     * @param triggerGroupName
     */  
    public static void removeJob(String jobName, String jobGroupName,
            String triggerName, String triggerGroupName) {
        try {  
            Scheduler sched = schedulerFactory.getScheduler();  
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
            sched.pauseTrigger(triggerKey);// 停止触发器  
            sched.unscheduleJob(triggerKey);// 移除触发器  
            sched.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 删除任务
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  

    /** 
     * @Description:启动所有定时任务 
     */  
    public static void startJobs() {  
        try {  
            Scheduler sched = schedulerFactory.getScheduler();  
            sched.start();  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  

    /** 
     * @Description:关闭所有定时任务 
     */  
    public static void shutdownJobs() {  
        try {  
            Scheduler sched = schedulerFactory.getScheduler();  
            if (!sched.isShutdown()) {  
                sched.shutdown();  
            }  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }

    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        try {
            CronTriggerImpl cronTriggerImpl = new CronTriggerImpl();
            cronTriggerImpl.setCronExpression("1/59 1/1 * * * ? *");
            // 这个是重点，一行代码搞定
            List<Date> dates = TriggerUtils.computeFireTimes(cronTriggerImpl, null, 1);
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            for (Date date : dates) {
                System.out.println("111111"+dateFormat.format(date));
            }

        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

}
